#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[50];
    int id;
    float grades[10];
    int course_count;
} Student;

// 保存学生信息到文件
void save_students(Student students[], int student_count, const char *file_name) {
    FILE *file = fopen(file_name, "w");
    if (file == NULL) {
        printf("无法打开文件进行保存。\n");
        return;
    }
    for (int i = 0; i < student_count; i++) {
        fprintf(file, "%s %d %d ", students[i].name, students[i].id, students[i].course_count);
        for (int j = 0; j < students[i].course_count; j++) {
            fprintf(file, "%.2f ", students[i].grades[j]);
        }
        fprintf(file, "\n");
    }
    fclose(file);
}
// 从文件加载学生信息
void load_students(Student students[], int *student_count, const char *file_name) {
    FILE *file = fopen(file_name, "r");
    if (file == NULL) {
        return;
    }
    *student_count = 0;
    while (*student_count < 100 && fscanf(file, "%s %d %d", students[*student_count].name, &students[*student_count].id, &students[*student_count].course_count) == 3) {
        for (int j = 0; j < students[*student_count].course_count; j++) {
            fscanf(file, "%f", &students[*student_count].grades[j]);
        }
        (*student_count)++;
    }
    fclose(file);
}

// 增加学生信息
void add_student(Student students[], int *student_count, const char *file_name) {
    if (*student_count >= 100) {
        printf("学生数量已达到上限，无法添加更多学生。\n");
        return;
    }
    Student new_student;
    printf("请输入学生姓名: ");
    scanf("%s", new_student.name);
    printf("请输入学生 ID: ");
    while (scanf("%d", &new_student.id) != 1) {
        while (getchar() != '\n');
        printf("输入无效，请输入一个有效的整数: ");
    }
    new_student.course_count = 0;
    students[*student_count] = new_student;
    (*student_count)++;
    save_students(students, *student_count, file_name);
    printf("学生信息添加成功。\n");
}

// 删除学生信息
void delete_student(Student students[], int *student_count, const char *file_name) {
    int id;
    printf("请输入要删除的学生 ID: ");
    while (scanf("%d", &id) != 1) {
        while (getchar() != '\n');
        printf("输入无效，请输入一个有效的整数: ");
    }
    for (int i = 0; i < *student_count; i++) {
        if (students[i].id == id) {
            for (int j = i; j < *student_count - 1; j++) {
                students[j] = students[j + 1];
            }
            (*student_count)--;
            save_students(students, *student_count, file_name);
            printf("学生信息删除成功。\n");
            return;
        }
    }
    printf("未找到该学生 ID。\n");
}

// 修改学生信息
void modify_student(Student students[], int student_count, const char *file_name) {
    int id;
    printf("请输入要修改的学生 ID: ");
    while (scanf("%d", &id) != 1) {
        while (getchar() != '\n');
        printf("输入无效，请输入一个有效的整数: ");
    }
    for (int i = 0; i < student_count; i++) {
        if (students[i].id == id) {
            printf("请输入新的学生姓名: ");
            scanf("%s", students[i].name);
            save_students(students, student_count, file_name);
            printf("学生信息修改成功。\n");
            return;
        }
    }
    printf("未找到该学生 ID。\n");
}

// 录入单科成绩
void enter_grades(Student students[], int student_count, const char *file_name) {
    const char *course_names[10] = {"数学", "语文", "英语", "物理", "化学", "生物", "历史", "地理", "政治", "体育"};
    int course_index;
    printf("可用的科目有：\n");
    for (int i = 0; i < 10; i++) {
        printf("%d. %s\n", i, course_names[i]);
    }
    printf("请输入要录入成绩的科目代号 (从 0 开始): ");
    while (scanf("%d", &course_index) != 1 || course_index < 0 || course_index >= 10) {
        while (getchar() != '\n');
        printf("科目代号无效，请输入 0 到 9 之间的数字: ");
    }
    for (int i = 0; i < student_count; i++) {
        float grade;
        printf("请输入学生 ID 为 %d，姓名为 %s 的 %s 科目成绩: ", students[i].id, students[i].name, course_names[course_index]);
        while (1) {
            if (scanf("%f", &grade) != 1) {
                while (getchar() != '\n');
                printf("输入无效，请输入一个有效的数字: ");
                continue;
            }
            if (grade < 0 || grade > 100) {
                printf("成绩超出正常范围 (0 - 100)，请重新输入: ");
            } else {
                students[i].grades[course_index] = grade;
                if (students[i].course_count <= course_index) {
                    students[i].course_count = course_index + 1;
                }
                break;
            }
        }
    }
    save_students(students, student_count, file_name);
    printf("成绩录入结束。\n");
}

// 班级内单科成绩排名
void rank_grades(Student students[], int student_count) {
    if (student_count == 0) {
        printf("没有学生信息，无法进行排名。\n");
        return;
    }
    const char *course_names[10] = {"数学", "语文", "英语", "物理", "化学", "生物", "历史", "地理", "政治", "体育"};
    int course_index;
    printf("请输入要排名的课程索引 (从 0 开始): ");
    while (scanf("%d", &course_index) != 1 || course_index < 0 || course_index >= 10) {
        while (getchar() != '\n');
        printf("课程索引无效，请输入 0 到 9 之间的数字: ");
    }
    for (int i = 0; i < student_count - 1; i++) {
        for (int j = i + 1; j < student_count; j++) {
            if (students[i].grades[course_index] < students[j].grades[course_index]) {
                Student temp = students[i];
                students[i] = students[j];
                students[j] = temp;
            }
        }
    }
    printf("班级内单科成绩排名如下:\n");
    for (int i = 0; i < student_count; i++) {
        printf("姓名: %s, ID: %d, %s 成绩: %.2f\n", students[i].name, students[i].id, course_names[course_index], students[i].grades[course_index]);
    }
}

// 查询某个学生的各科成绩
void query_grades(Student students[], int student_count) {
    const char *course_names[10] = {"数学", "语文", "英语", "物理", "化学", "生物", "历史", "地理", "政治", "体育"};
    int id;
    printf("请输入要查询的学生 ID: ");
    while (scanf("%d", &id) != 1) {
        while (getchar() != '\n');
        printf("输入无效，请输入一个有效的整数: ");
    }
    for (int i = 0; i < student_count; i++) {
        if (students[i].id == id) {
            printf("学生姓名: %s, ID: %d\n", students[i].name, students[i].id);
            for (int j = 0; j < students[i].course_count; j++) {
                printf("%s 成绩: %.2f\n", course_names[j], students[i].grades[j]);
            }
            return;
        }
    }
    printf("未找到该学生 ID。\n");
}

// 统计所有不及格科目超过 2 科的学生名单
void count_failing_students(Student students[], int student_count) {
    printf("不及格科目超过 2 科的学生名单:\n");
    for (int i = 0; i < student_count; i++) {
        int fail_count = 0;
        for (int j = 0; j < students[i].course_count; j++) {
            if (students[i].grades[j] < 60) {
                fail_count++;
            }
        }
        if (fail_count > 2) {
            printf("姓名: %s, ID: %d\n", students[i].name, students[i].id);
        }
    }
}

int main() {
    Student students[100];
    int student_count = 0;
    int choice;
    const char *file_name = "students.txt";

    load_students(students, &student_count, file_name);

    do {
        printf("\n学生成绩管理系统\n");
        printf("1. 增加学生信息\n");
        printf("2. 删除学生信息\n");
        printf("3. 修改学生信息\n");
        printf("4. 录入单科成绩\n");
        printf("5. 班级内单科成绩排名\n");
        printf("6. 查询某个学生的各科成绩\n");
        printf("7. 统计所有不及格科目超过 2 科的学生名单\n");
        printf("0. 退出\n");
        printf("请输入你的选择: ");
        while (scanf("%d", &choice) != 1) {
            while (getchar() != '\n');
            printf("输入无效，请输入一个有效的整数: ");
        }

        switch (choice) {
            case 1:
                add_student(students, &student_count, file_name);
                break;
            case 2:
                delete_student(students, &student_count, file_name);
                break;
            case 3:
                modify_student(students, student_count, file_name);
                break;
            case 4:
                enter_grades(students, student_count, file_name);
                break;
            case 5:
                rank_grades(students, student_count);
                break;
            case 6:
                query_grades(students, student_count);
                break;
            case 7:
                count_failing_students(students, student_count);
                break;
            case 0:
                printf("退出系统。\n");
                break;
            default:
                printf("无效的选择，请重新输入。\n");
        }
    } while (choice != 0);

    return 0;
}    